﻿using System;
using System.Threading.Tasks;
using Devonline.Core;
using Devonline.Entity;
using Devonline.MessageClient;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Serilog;

namespace MessageClientTest
{
    internal class Program
    {
        private static ChannelClient<string> _client;
        private static ILogger<Program> _logger;
        private static TestSetting _appSetting;

        /// <summary>
        /// 启动消息中心客户端测试程序
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        public static async Task Main(string[] args)
        {
            var host = CreateHostBuilder(args).Build();
            host.Start();

            _logger = host.Services.GetService<ILogger<Program>>();
            _client = host.Services.GetService<ChannelClient<string>>();
            if (_client != null)
            {
                _client.OnReceive(OnMessage);
                _client.OnAck();
                await _client.StartAsync();

                var input = Console.ReadLine();
                while (input != "exit")
                {
                    var message = new Message { Content = input, Receiver = _appSetting.Receiver };
                    await _client.SendAsync(message);
                    input = Console.ReadLine();
                }

                await _client.StopAsync();
                await host.StopAsync();
                _logger.LogInformation("客户端退出, 消息中心连接结束!");
            }
        }

        /// <summary>
        /// 构建 host
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
            .UseSerilog((context, logger) => logger.ReadFrom.Configuration(context.Configuration))
            .ConfigureServices((hostContext, services) =>
            {
                _appSetting = services.AddAppSettings<TestSetting>();
                services.AddLogging();
                services.AddSingleton<ClientSetting>(_appSetting);
                services.AddSingleton<ChannelClient<string>>();
            });

        /// <summary>
        /// 收到消息时的处理方法
        /// </summary>
        /// <param name="message"></param>
        static void OnMessage(Message<string> message)
        {
            if (message.Sender == _client.ClientId && message.Type == MessageType.Ack)
            {
                _logger.LogInformation("Yes, I receive the ACK message from {receiver} at {receiveTime}!", message.Receiver, message.ReceiveTime);
            }
            else
            {
                _logger.LogInformation("Yes, I receive the {messageType} message: {content} from {sender} at {receiveTime}!", message.Type, message.Content, message.Sender, message.ReceiveTime);
            }
        }
    }
}
